/**
 * @公历农历互转工具类
 * 可以对当前日期和自定义搜索日期进行公历与农历的查询，因为下方备注较为详细，故可在下方找到对应的方法进行查看，不做其他赘述。
 *
 * @打点调用方法
 * @lunarCalendarQuery 当前日期转农历查询函数
 * @gregorianCalendarQuery 农历查询转换公历函数
 * @leapYearMonthDay 获取农历某年中某个月的天数
 * @twentyFourSolarTermsQuery 查询公历某年中那个24节气的具体时间
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// 接口区域
// 错误函数校验类型
type error =
  | 'year'
  | 'month'
  | 'gregorianCalendarMonthDay'
  | 'lunarCalendarMonthDay'
  | 'lunarCalendarOrigin'
  | 'twentyFourSolarTerms'

// 抛出错误函数接口
interface LunarCalendarConversionErr {
  (error: Partial<Record<error, boolean>>): boolean
}

// 工具类本体
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
export default class LunarCalendarConversion {
  /**
   * @农历年份信息查询表
   * 1900-2100的年份中每年月份日期+是否闰年情况
   * 此为16进制加密
   */
  protected queryOfLunarYearDetails: number[] = [
    0x04bd8,
    0x04ae0,
    0x0a570,
    0x054d5,
    0x0d260,
    0x0d950,
    0x16554,
    0x056a0,
    0x09ad0,
    0x055d2, // 1900-1909

    0x04ae0,
    0x0a5b6,
    0x0a4d0,
    0x0d250,
    0x1d255,
    0x0b540,
    0x0d6a0,
    0x0ada2,
    0x095b0,
    0x14977, // 1910-1919

    0x04970,
    0x0a4b0,
    0x0b4b5,
    0x06a50,
    0x06d40,
    0x1ab54,
    0x02b60,
    0x09570,
    0x052f2,
    0x04970, // 1920-1929

    0x06566,
    0x0d4a0,
    0x0ea50,
    0x06e95,
    0x05ad0,
    0x02b60,
    0x186e3,
    0x092e0,
    0x1c8d7,
    0x0c950, // 1930-1939

    0x0d4a0,
    0x1d8a6,
    0x0b550,
    0x056a0,
    0x1a5b4,
    0x025d0,
    0x092d0,
    0x0d2b2,
    0x0a950,
    0x0b557, // 1940-1949

    0x06ca0,
    0x0b550,
    0x15355,
    0x04da0,
    0x0a5b0,
    0x14573,
    0x052b0,
    0x0a9a8,
    0x0e950,
    0x06aa0, // 1950-1959

    0x0aea6,
    0x0ab50,
    0x04b60,
    0x0aae4,
    0x0a570,
    0x05260,
    0x0f263,
    0x0d950,
    0x05b57,
    0x056a0, // 1960-1969

    0x096d0,
    0x04dd5,
    0x04ad0,
    0x0a4d0,
    0x0d4d4,
    0x0d250,
    0x0d558,
    0x0b540,
    0x0b6a0,
    0x195a6, // 1970-1979

    0x095b0,
    0x049b0,
    0x0a974,
    0x0a4b0,
    0x0b27a,
    0x06a50,
    0x06d40,
    0x0af46,
    0x0ab60,
    0x09570, // 1980-1989

    0x04af5,
    0x04970,
    0x064b0,
    0x074a3,
    0x0ea50,
    0x06b58,
    0x05ac0,
    0x0ab60,
    0x096d5,
    0x092e0, // 1990-1999

    0x0c960,
    0x0d954,
    0x0d4a0,
    0x0da50,
    0x07552,
    0x056a0,
    0x0abb7,
    0x025d0,
    0x092d0,
    0x0cab5, // 2000-2009

    0x0a950,
    0x0b4a0,
    0x0baa4,
    0x0ad50,
    0x055d9,
    0x04ba0,
    0x0a5b0,
    0x15176,
    0x052b0,
    0x0a930, // 2010-2019

    0x07954,
    0x06aa0,
    0x0ad50,
    0x05b52,
    0x04b60,
    0x0a6e6,
    0x0a4e0,
    0x0d260,
    0x0ea65,
    0x0d530, // 2020-2029

    0x05aa0,
    0x076a3,
    0x096d0,
    0x04afb,
    0x04ad0,
    0x0a4d0,
    0x1d0b6,
    0x0d250,
    0x0d520,
    0x0dd45, // 2030-2039

    0x0b5a0,
    0x056d0,
    0x055b2,
    0x049b0,
    0x0a577,
    0x0a4b0,
    0x0aa50,
    0x1b255,
    0x06d20,
    0x0ada0, // 2040-2049

    0x14b63,
    0x09370,
    0x049f8,
    0x04970,
    0x064b0,
    0x168a6,
    0x0ea50,
    0x06b20,
    0x1a6c4,
    0x0aae0, // 2050-2059

    0x0a2e0,
    0x0d2e3,
    0x0c960,
    0x0d557,
    0x0d4a0,
    0x0da50,
    0x05d55,
    0x056a0,
    0x0a6d0,
    0x055d4, // 2060-2069

    0x052d0,
    0x0a9b8,
    0x0a950,
    0x0b4a0,
    0x0b6a6,
    0x0ad50,
    0x055a0,
    0x0aba4,
    0x0a5b0,
    0x052b0, // 2070-2079

    0x0b273,
    0x06930,
    0x07337,
    0x06aa0,
    0x0ad50,
    0x14b55,
    0x04b60,
    0x0a570,
    0x054e4,
    0x0d160, // 2080-2089

    0x0e968,
    0x0d520,
    0x0daa0,
    0x16aa6,
    0x056d0,
    0x04ae0,
    0x0a9d4,
    0x0a2d0,
    0x0d150,
    0x0f252, // 2090-2099

    0x0d520, // 2100
  ]

  /**
   * @公历每月日期对应数组
   * 1900-2100的年份中每年月份日期+是否闰年情况
   * 此为16进制加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected gregorianCalendarMonthDate: number[] = [
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
  ]

  /**
   * @星期转换汉字数组
   *  ['日','一','二','三','四','五','六','七','八','九','十']
   * 为UTF-8编码加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

  protected weekList: string[] = [
    '\u65e5',
    '\u4e00',
    '\u4e8c',
    '\u4e09',
    '\u56db',
    '\u4e94',
    '\u516d',
  ]

  /**
   * @月份查询字符串数组
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected monthList: string[] = [
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    '10',
    '11',
    '12',
  ]

  /**
   * @天干查询数组
   * ['甲','乙','丙','丁','戊','己','庚','辛','壬','癸']
   * 为UTF-8编码加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected heavenlyStemsList: string[] = [
    '\u7532',
    '\u4e59',
    '\u4e19',
    '\u4e01',
    '\u620a',
    '\u5df1',
    '\u5e9a',
    '\u8f9b',
    '\u58ec',
    '\u7678',
  ]

  /**
   * @地支查询数组
   * ['子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥']
   * 为UTF-8编码加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected terrestrialBranchList: string[] = [
    '\u5b50',
    '\u4e11',
    '\u5bc5',
    '\u536f',
    '\u8fb0',
    '\u5df3',
    '\u5348',
    '\u672a',
    '\u7533',
    '\u9149',
    '\u620c',
    '\u4ea5',
  ]

  /**
   * @生肖查询数组
   * ['鼠','牛','虎','兔','龙','蛇','马','羊','猴','鸡','狗','猪']
   * 为UTF-8编码加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected chineseZodiac: string[] = [
    '\u9f20',
    '\u725b',
    '\u864e',
    '\u5154',
    '\u9f99',
    '\u86c7',
    '\u9a6c',
    '\u7f8a',
    '\u7334',
    '\u9e21',
    '\u72d7',
    '\u732a',
  ]

  /**
   * @二十四节气查询数组
   * ['小寒','大寒','立春','雨水','惊蛰','春分','清明','谷雨','立夏','小满','芒种','夏至','小暑','大暑','立秋','处暑','白露','秋分','寒露','霜降','立冬','小雪','大雪','冬至']
   * 为UTF-8编码加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected twentyFourSolarTerms: string[] = [
    '\u5c0f\u5bd2',
    '\u5927\u5bd2',
    '\u7acb\u6625',
    '\u96e8\u6c34',
    '\u60ca\u86f0',
    '\u6625\u5206',
    '\u6e05\u660e',
    '\u8c37\u96e8',
    '\u7acb\u590f',
    '\u5c0f\u6ee1',
    '\u8292\u79cd',
    '\u590f\u81f3',
    '\u5c0f\u6691',
    '\u5927\u6691',
    '\u7acb\u79cb',
    '\u5904\u6691',
    '\u767d\u9732',
    '\u79cb\u5206',
    '\u5bd2\u9732',
    '\u971c\u964d',
    '\u7acb\u51ac',
    '\u5c0f\u96ea',
    '\u5927\u96ea',
    '\u51ac\u81f3',
  ]

  /**
   * @二十四节气日期速查数组
   * 1900-2100各年的24节气对应时间点，从小寒开始
   * 16进制加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected twentyFourSolarTermsList: string[] = [
    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',
    '97bcf97c3598082c95f8c965cc920f',

    '97bd0b06bdb0722c965ce1cfcc920f',
    'b027097bd097c36b0b6fc9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',

    '97bcf97c359801ec95f8c965cc920f',
    '97bd0b06bdb0722c965ce1cfcc920f',
    'b027097bd097c36b0b6fc9274c91aa',

    '97b6b97bd19801ec9210c965cc920e',
    '97bcf97c359801ec95f8c965cc920f',
    '97bd0b06bdb0722c965ce1cfcc920f',

    'b027097bd097c36b0b6fc9274c91aa',
    '9778397bd19801ec9210c965cc920e',
    '97b6b97bd19801ec95f8c965cc920f',

    '97bd09801d98082c95f8e1cfcc920f',
    '97bd097bd097c36b0b6fc9210c8dc2',
    '9778397bd197c36c9210c9274c91aa',

    '97b6b97bd19801ec95f8c965cc920e',
    '97bd09801d98082c95f8e1cfcc920f',
    '97bd097bd097c36b0b6fc9210c8dc2',

    '9778397bd097c36c9210c9274c91aa',
    '97b6b97bd19801ec95f8c965cc920e',
    '97bcf97c3598082c95f8e1cfcc920f',

    '97bd097bd097c36b0b6fc9210c8dc2',
    '9778397bd097c36c9210c9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',

    '97bcf97c3598082c95f8c965cc920f',
    '97bd097bd097c35b0b6fc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',

    '97b6b97bd19801ec9210c965cc920e',
    '97bcf97c3598082c95f8c965cc920f',
    '97bd097bd097c35b0b6fc920fb0722',

    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',
    '97bcf97c359801ec95f8c965cc920f',

    '97bd097bd097c35b0b6fc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',

    '97bcf97c359801ec95f8c965cc920f',
    '97bd097bd097c35b0b6fc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',

    '97b6b97bd19801ec9210c965cc920e',
    '97bcf97c359801ec95f8c965cc920f',
    '97bd097bd07f595b0b6fc920fb0722',

    '9778397bd097c36b0b6fc9210c8dc2',
    '9778397bd19801ec9210c9274c920e',
    '97b6b97bd19801ec95f8c965cc920f',

    '97bd07f5307f595b0b0bc920fb0722',
    '7f0e397bd097c36b0b6fc9210c8dc2',
    '9778397bd097c36c9210c9274c920e',

    '97b6b97bd19801ec95f8c965cc920f',
    '97bd07f5307f595b0b0bc920fb0722',
    '7f0e397bd097c36b0b6fc9210c8dc2',

    '9778397bd097c36c9210c9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',
    '97bd07f1487f595b0b0bc920fb0722',

    '7f0e397bd097c36b0b6fc9210c8dc2',
    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',

    '97bcf7f1487f595b0b0bb0b6fb0722',
    '7f0e397bd097c35b0b6fc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',

    '97b6b97bd19801ec9210c965cc920e',
    '97bcf7f1487f595b0b0bb0b6fb0722',
    '7f0e397bd097c35b0b6fc920fb0722',

    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',
    '97bcf7f1487f531b0b0bb0b6fb0722',

    '7f0e397bd097c35b0b6fc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b97bd19801ec9210c965cc920e',

    '97bcf7f1487f531b0b0bb0b6fb0722',
    '7f0e397bd07f595b0b6fc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',

    '97b6b97bd19801ec9210c9274c920e',
    '97bcf7f0e47f531b0b0bb0b6fb0722',
    '7f0e397bd07f595b0b0bc920fb0722',

    '9778397bd097c36b0b6fc9210c91aa',
    '97b6b97bd197c36c9210c9274c920e',
    '97bcf7f0e47f531b0b0bb0b6fb0722',

    '7f0e397bd07f595b0b0bc920fb0722',
    '9778397bd097c36b0b6fc9210c8dc2',
    '9778397bd097c36c9210c9274c920e',

    '97b6b7f0e47f531b0723b0b6fb0722',
    '7f0e37f5307f595b0b0bc920fb0722',
    '7f0e397bd097c36b0b6fc9210c8dc2',

    '9778397bd097c36b0b70c9274c91aa',
    '97b6b7f0e47f531b0723b0b6fb0721',
    '7f0e37f1487f595b0b0bb0b6fb0722',

    '7f0e397bd097c35b0b6fc9210c8dc2',
    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b7f0e47f531b0723b0b6fb0721',

    '7f0e27f1487f595b0b0bb0b6fb0722',
    '7f0e397bd097c35b0b6fc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',

    '97b6b7f0e47f531b0723b0b6fb0721',
    '7f0e27f1487f531b0b0bb0b6fb0722',
    '7f0e397bd097c35b0b6fc920fb0722',

    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b7f0e47f531b0723b0b6fb0721',
    '7f0e27f1487f531b0b0bb0b6fb0722',

    '7f0e397bd097c35b0b6fc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',
    '97b6b7f0e47f531b0723b0b6fb0721',

    '7f0e27f1487f531b0b0bb0b6fb0722',
    '7f0e397bd07f595b0b0bc920fb0722',
    '9778397bd097c36b0b6fc9274c91aa',

    '97b6b7f0e47f531b0723b0787b0721',
    '7f0e27f0e47f531b0b0bb0b6fb0722',
    '7f0e397bd07f595b0b0bc920fb0722',

    '9778397bd097c36b0b6fc9210c91aa',
    '97b6b7f0e47f149b0723b0787b0721',
    '7f0e27f0e47f531b0723b0b6fb0722',

    '7f0e397bd07f595b0b0bc920fb0722',
    '9778397bd097c36b0b6fc9210c8dc2',
    '977837f0e37f149b0723b0787b0721',

    '7f07e7f0e47f531b0723b0b6fb0722',
    '7f0e37f5307f595b0b0bc920fb0722',
    '7f0e397bd097c35b0b6fc9210c8dc2',

    '977837f0e37f14998082b0787b0721',
    '7f07e7f0e47f531b0723b0b6fb0721',
    '7f0e37f1487f595b0b0bb0b6fb0722',

    '7f0e397bd097c35b0b6fc9210c8dc2',
    '977837f0e37f14998082b0787b06bd',
    '7f07e7f0e47f531b0723b0b6fb0721',

    '7f0e27f1487f531b0b0bb0b6fb0722',
    '7f0e397bd097c35b0b6fc920fb0722',
    '977837f0e37f14998082b0787b06bd',

    '7f07e7f0e47f531b0723b0b6fb0721',
    '7f0e27f1487f531b0b0bb0b6fb0722',
    '7f0e397bd097c35b0b6fc920fb0722',

    '977837f0e37f14998082b0787b06bd',
    '7f07e7f0e47f531b0723b0b6fb0721',
    '7f0e27f1487f531b0b0bb0b6fb0722',

    '7f0e397bd07f595b0b0bc920fb0722',
    '977837f0e37f14998082b0787b06bd',
    '7f07e7f0e47f531b0723b0b6fb0721',

    '7f0e27f1487f531b0b0bb0b6fb0722',
    '7f0e397bd07f595b0b0bc920fb0722',
    '977837f0e37f14998082b0787b06bd',

    '7f07e7f0e47f149b0723b0787b0721',
    '7f0e27f0e47f531b0b0bb0b6fb0722',
    '7f0e397bd07f595b0b0bc920fb0722',

    '977837f0e37f14998082b0723b06bd',
    '7f07e7f0e37f149b0723b0787b0721',
    '7f0e27f0e47f531b0723b0b6fb0722',

    '7f0e397bd07f595b0b0bc920fb0722',
    '977837f0e37f14898082b0723b02d5',
    '7ec967f0e37f14998082b0787b0721',

    '7f07e7f0e47f531b0723b0b6fb0722',
    '7f0e37f1487f595b0b0bb0b6fb0722',
    '7f0e37f0e37f14898082b0723b02d5',

    '7ec967f0e37f14998082b0787b0721',
    '7f07e7f0e47f531b0723b0b6fb0722',
    '7f0e37f1487f531b0b0bb0b6fb0722',

    '7f0e37f0e37f14898082b0723b02d5',
    '7ec967f0e37f14998082b0787b06bd',
    '7f07e7f0e47f531b0723b0b6fb0721',

    '7f0e37f1487f531b0b0bb0b6fb0722',
    '7f0e37f0e37f14898082b072297c35',
    '7ec967f0e37f14998082b0787b06bd',

    '7f07e7f0e47f531b0723b0b6fb0721',
    '7f0e27f1487f531b0b0bb0b6fb0722',
    '7f0e37f0e37f14898082b072297c35',

    '7ec967f0e37f14998082b0787b06bd',
    '7f07e7f0e47f531b0723b0b6fb0721',
    '7f0e27f1487f531b0b0bb0b6fb0722',

    '7f0e37f0e366aa89801eb072297c35',
    '7ec967f0e37f14998082b0787b06bd',
    '7f07e7f0e47f149b0723b0787b0721',

    '7f0e27f1487f531b0b0bb0b6fb0722',
    '7f0e37f0e366aa89801eb072297c35',
    '7ec967f0e37f14998082b0723b06bd',

    '7f07e7f0e47f149b0723b0787b0721',
    '7f0e27f0e47f531b0723b0b6fb0722',
    '7f0e37f0e366aa89801eb072297c35',

    '7ec967f0e37f14998082b0723b06bd',
    '7f07e7f0e37f14998083b0787b0721',
    '7f0e27f0e47f531b0723b0b6fb0722',

    '7f0e37f0e366aa89801eb072297c35',
    '7ec967f0e37f14898082b0723b02d5',
    '7f07e7f0e37f14998082b0787b0721',

    '7f07e7f0e47f531b0723b0b6fb0722',
    '7f0e36665b66aa89801e9808297c35',
    '665f67f0e37f14898082b0723b02d5',

    '7ec967f0e37f14998082b0787b0721',
    '7f07e7f0e47f531b0723b0b6fb0722',
    '7f0e36665b66a449801e9808297c35',

    '665f67f0e37f14898082b0723b02d5',
    '7ec967f0e37f14998082b0787b06bd',
    '7f07e7f0e47f531b0723b0b6fb0721',

    '7f0e36665b66a449801e9808297c35',
    '665f67f0e37f14898082b072297c35',
    '7ec967f0e37f14998082b0787b06bd',

    '7f07e7f0e47f531b0723b0b6fb0721',
    '7f0e26665b66a449801e9808297c35',
    '665f67f0e37f1489801eb072297c35',

    '7ec967f0e37f14998082b0787b06bd',
    '7f07e7f0e47f531b0723b0b6fb0721',
    '7f0e27f1487f531b0b0bb0b6fb0722',
  ]

  /**
   * @日期转农历称呼查询数组
   * ['初','十','廿','卅']
   * 为UTF-8编码加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected lunarDateTitle: string[] = ['\u521d', '\u5341', '\u5eff', '\u5345']

  /**
   * @月份转农历称呼速查表
   * ['正','二','三','四','五','六','七','八','九','十','冬','腊']
   * 为UTF-8编码加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected lunarMonthAppellation: string[] = [
    '\u6b63',
    '\u4e8c',
    '\u4e09',
    '\u56db',
    '\u4e94',
    '\u516d',
    '\u4e03',
    '\u516b',
    '\u4e5d',
    '\u5341',
    '\u51ac',
    '\u814a',
  ]

  /**
   * @数字转中文数组
   * ['一','二','三','四','五','六','七','八','九','十']
   * 为UTF-8编码加密
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected chineseNumber: string[] = [
    '\u3007',
    '\u4e00',
    '\u4e8c',
    '\u4e09',
    '\u56db',
    '\u4e94',
    '\u516d',
    '\u4e03',
    '\u516b',
    '\u4e5d',
    '\u5341',
  ]

  /**
   * @用户使用时间存储对象
   * year 当前用户输入的年份
   * month 当前用户输入的月份
   * day 当前用户输入的日期
   * index 当前查询的二十四节气位置
   * isLunarCalendar 当前查询的二十四节气位置
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected userInputTime = {
    year: 0,
    month: 0,
    day: 0,
    isLeap: false,
    index: 0,
    isLunarCalendar: false,
  }

  // 构造函数
  constructor() {}

  /**
   * @错误提醒函数
   * @error 错误指定判断对象，每个成员都是一个布尔值，默认都是关闭的，只有指定了才能打开
   * year 年份校验
   * month 月份校验
   * gregorianCalendarMonthDay 公历每月天数校验
   * lunarCalendarMonthDay 农历每月天数校验
   * lunarCalendarOrigin 农历原点校验
   * twentyFourSolarTerms 二十四节气校验
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected Errors: LunarCalendarConversionErr = (error) => {
    // 结构出需要的参数进行处理
    const {
      year = false,
      month = false,
      gregorianCalendarMonthDay = false,
      lunarCalendarMonthDay = false,
      lunarCalendarOrigin = false,
      twentyFourSolarTerms = false,
    } = error

    // 若是需要进行年份校验
    // -------------------------------------------------------------------------------------------------------
    if (year) {
      if (this.userInputTime.year < 1900 || this.userInputTime.year >= 2100) {
        console.error(
          '年份不能小于1900，也不能大于或等于2100，请检查输入的年份值，当前输入年份为' +
            this.userInputTime.year
        )
        return false
      }
    }

    // 若是需要进行月份校验
    // -------------------------------------------------------------------------------------------------------
    if (month) {
      if (this.userInputTime.month > 12 || this.userInputTime.month < 1) {
        console.error(
          `请检查输入的月份是否正确，月份不能小于1；也不能大于12，当前查询月份为${this.userInputTime.month}`
        )
        return false
      }
    }

    // 若是需要公历月份具体日期校验
    // -------------------------------------------------------------------------------------------------------
    if (gregorianCalendarMonthDay) {
      // 查询当前输入月份是否满足公历月份的格式
      let monthDay = this.yearMonthDay(
        this.userInputTime.year,
        this.userInputTime.month
      )
      if (this.userInputTime.day < 1 || this.userInputTime.day > monthDay) {
        console.error(
          `请检查输入的日期是否正确，日期不能小于1；也不能大于当前月份中的日期最大值，当前月份最大值为${monthDay}，当前查询日期为${this.userInputTime.day}`
        )
        return false
      }
    }

    // 若是需要农历历月份具体日期校验
    // -------------------------------------------------------------------------------------------------------
    if (lunarCalendarMonthDay) {
      // 检查此月是否是有闰月
      let monthDay = this.leapYearMonthDay(
        this.userInputTime.year,
        this.userInputTime.month,
        this.userInputTime.isLeap
      )
      // 不是闰月时则进行拦截
      if (!monthDay) {
        return false
      }
      if (this.userInputTime.day < 1 || this.userInputTime.day > monthDay) {
        console.error(
          `请检查输入的日期是否正确，日期不能小于1；也不能大于当前月份中的日期最大值，当前月份最大值为${monthDay}，当前查询日期为${this.userInputTime.day}`
        )
        return false
      }
    }

    // 若是需要农历原点校验
    // -------------------------------------------------------------------------------------------------------
    if (lunarCalendarOrigin) {
      if (
        this.userInputTime.year === 1900 &&
        this.userInputTime.month === 1 &&
        this.userInputTime.day < 31
      ) {
        console.error(
          `农历原点为1900年1月31日，不能查询农历原点前的时间，当前查询的内容为${this.userInputTime.year}年${this.userInputTime.month}月${this.userInputTime.day}日`
        )
        return false
      }
    }

    // 若是需要二十四节气校验
    // -------------------------------------------------------------------------------------------------------
    if (twentyFourSolarTerms) {
      if (this.userInputTime.index < 1 || this.userInputTime.index > 24) {
        console.error(
          '二十四节气查询内容不能小于1，也不能大于24，请检查输入的具体查询值，当前输入的查询值为' +
            this.userInputTime.index
        )
        return false
      }
    }

    return true
  }

  /**
   * @当前日期距离1900年1月30日计算原点的天数差
   * @year 对应公历的年份
   * @month 对应的月份
   * @day 对应的日期
   * 返回计算后的天数
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected timeDifference = (year: number, month: number, day: number) => {
    // 得到农历原点到时间戳的天数+1,因为31干支为 甲辰方便计算干支，但是农历天数则需要+1作为平衡
    let timeStampDifference = Date.UTC(1900, 0, 31, 0, 0, 0, 0) / 86400000
    // 当前日期到时间的天数
    let CurrentTimestampDifference =
      Date.UTC(year, month - 1, day, 0, 0, 0, 0) / 86400000

    // 一共的天数差值
    return CurrentTimestampDifference - timeStampDifference
  }

  /**
   * @判断当年农历是否是闰年
   * @year对应农历的年份
   * @返回一个对象
   * conclusion : 布尔值，是闰年则是true，不是则是false
   * leapMonth : 数值，代表闰的那个月份,若不是则为0
   * leapMonthDay : 数值，代表此闰月有多少天, 若不是则为0
   * conversion : 16进制年份换算为2进制后的具体字符串
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected isLeapYear = (year: number) => {
    // 将符合规范的参数带入 农历年份信息查询表 中进行筛选并变为2进制代码
    let conversion = this.queryOfLunarYearDetails[year - 1900].toString(2)

    // 根据得到的2进制长度进行补齐20位
    for (let index = 0; ; index++) {
      conversion = '0' + conversion

      if (conversion.length === 20) {
        break
      }
    }

    // 截取最后4位字符串，作为闰年判断依据
    let leapText = conversion.slice(-4)
    // 判断是否是闰月
    let conclusion = leapText !== '0000'
    // 闰月的大小
    let leapMonthDay = conclusion
      ? parseInt(conversion.slice(0, 4)) === 1
        ? 30
        : 29
      : 0

    // 将结果返回
    return {
      conclusion,
      // 如果是闰年，则将月份的具体名称从二进制转成10进制，否则返回0
      leapMonth: conclusion ? parseInt(leapText, 2) : 0,
      leapMonthDay,
      conversion,
    }
  }

  /**
   * @计算农历某年一整年的总天数
   * @year对应农历的年份
   * @返回当年的总天数
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected leapYearDays = (year: number) => {
    // 调用判断当年是否是闰年的函数,并结构出闰年判断值+闰月的天数+2进制后的年份字符串
    const { conclusion, leapMonthDay, conversion } = this.isLeapYear(year)
    // 根据二进制字符串的长度进行判断年份内容对应的长度在哪里进行截取，15的长度时从首位开始，并要补齐头部一个'0',否则从1位置上截取
    let resultText = conversion.slice(4, -4)

    // 使用g表示整个字符串都要匹配，对其中1的个数进行匹配，1代表大月
    let regex = new RegExp('1', 'g')
    //match方法可在字符串内检索指定的值，或找到一个或多个正则表达式的匹配。
    let result = resultText.match(regex)

    // 将得到规则内容进行根据长度来计算年份天数, result代表大月30的个数，12-result表一年中小月的个数
    let yearDay = result.length * 30 + (12 - result.length) * 29
    // 如果是闰年则对计算后的值进行相加闰月的个数
    conclusion && (yearDay += leapMonthDay)

    // 弹出计算后的具体年份天数
    return yearDay
  }

  /**
   * @计算农历某年所有月份的天数分布
   * @year对应农历的年份
   * @返回一个对象
   * isLeapYear:是否是闰年
   * leapMonth:闰年的月份，不是闰年则为0
   * leapMonthDay: 对应的闰月天数，不是闰年则为0
   * monthObj对象中属性名:对应从一月到年尾的月份,按照1往后顺延，如果是有闰年，则是在对应的闰月名称后添加+表示此为闰月
   * monthObj对象中属性值:表示对应的月份天数
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected leapYearMonth = (year: number) => {
    // 调用判断当年是否是闰年的函数,并结构出对应的内容
    const { conclusion, leapMonth, leapMonthDay, conversion } =
      this.isLeapYear(year)
    // 根据返回字符串内容长度，进行截取需要的月份参数值
    let yearMonthText = conversion.slice(4, -4)

    // 创建月份的内容对象
    let monthObj = {}

    // 对 monthObj 进行赋值
    monthObj['1'] = Number(yearMonthText[0]) + 29
    monthObj['2'] = Number(yearMonthText[1]) + 29
    monthObj['3'] = Number(yearMonthText[2]) + 29
    monthObj['4'] = Number(yearMonthText[3]) + 29
    monthObj['5'] = Number(yearMonthText[4]) + 29
    monthObj['6'] = Number(yearMonthText[5]) + 29
    monthObj['7'] = Number(yearMonthText[6]) + 29
    monthObj['8'] = Number(yearMonthText[7]) + 29
    monthObj['9'] = Number(yearMonthText[8]) + 29
    monthObj['10'] = Number(yearMonthText[9]) + 29
    monthObj['11'] = Number(yearMonthText[10]) + 29
    monthObj['12'] = Number(yearMonthText[11]) + 29

    // 如果是闰年则对闰年进行赋值
    conclusion && (monthObj[leapMonth + '+'] = leapMonthDay)

    return {
      isLeapYear: conclusion,
      leapMonth,
      leapMonthDay,
      monthObj,
    }
  }

  /**
   * @获取农历某年中某个月的天数
   * @year对应农历的年份
   * @month对应农历的月份
   * @isLeap是否是查询的闰月_默认false
   * @返回当前搜索月份的天数
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  leapYearMonthDay = (year: number, month: number, isLeap = false) => {
    // 进行赋值验证
    this.userInputTime.year = year
    this.userInputTime.month = month
    // 若是有抛出错误则直接弹出
    if (!this.Errors({ year: true, month: true })) {
      return
    }
    // 调用判断当年是否是闰年的函数,并结构出对应的内容
    const { conclusion, leapMonth, leapMonthDay, conversion } =
      this.isLeapYear(year)

    // 错误条件提醒
    if (!conclusion && isLeap) {
      console.error(
        '查询的年份并不是闰年，请检查查询的 month月份 或 isLeap开关是否正确'
      )
      return
    } else if (conclusion && isLeap && leapMonth !== month) {
      console.error(
        '查询的年份所闰的月份为:' +
          leapMonth +
          '月，请检查 month参数 或 isLeap开关 是否正确'
      )
      return
    }

    // 同步用户输入的月份值
    this.userInputTime.month = month
    // 使用月份规则校验,若是不通过则直接弹出
    if (!this.Errors({ month: true })) {
      return
    }

    // 所需弹出查询的月份天数
    let needMonthDay: number

    // 根据返回字符串内容长度，进行截取需要的月份参数值
    let yearMonthText = conversion.slice(4, -4)

    // 如果不是查询闰月，则找到对应的月份进行赋值操作
    !isLeap && (needMonthDay = Number(yearMonthText[month - 1]) + 29)
    // 是查询闰月并且查询的月份和闰月的月份一样时，才对其赋值
    isLeap && leapMonth === month && (needMonthDay = leapMonthDay)

    return needMonthDay
  }

  /**
   * @公历年份某月天数查询
   * @year查询年份
   * @month查询月份
   *
   * @返回查询到的具体天数
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected yearMonthDay = (year: number, month: number) => {
    // 声明当前月份换算为查询数组的位置信息
    let monthIndex = month - 1

    // 2月份的闰平规律测算后确认返回28或29
    if (monthIndex === 1) {
      // 根据公历闰年计算规则，判断若是查询的2月应该为对应的具体天数
      return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0 ? 29 : 28
    } else {
      // 不是的话，直接弹出从数组中的具体内容
      return this.gregorianCalendarMonthDate[monthIndex]
    }
  }

  /**
   * 公历某年中总天数查询
   * @year查询年份
   * @返回查询到的具体天数
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected gregorianCalendarDay = (year: number) => {
    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0 ? 366 : 365
  }

  /**
   * @查询公历某年中那个24节气的具体时间
   * @year 查询的公历年份；y公历年(1900-2100)
   * @index 二十四节气中的第几个节气(0~23)；从index=1(小寒)算起
   * @返回一个查询对象
   * name:查询的具体二十四节气名称
   * month: 当前节气具体的公历月份
   * day:当前节气具体的公历月份
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  twentyFourSolarTermsQuery = (year: number, index: number) => {
    // 同步用户选择的二十四节气位置信息+时间信息
    this.userInputTime.index = index
    this.userInputTime.year = year
    // 若是调用校验函数有错，则直接弹出
    if (!this.Errors({ year: true, twentyFourSolarTerms: true })) {
      return
    }

    // 从24节气查询数组中找到对应查询参数
    let processingData = this.twentyFourSolarTermsList[year - 1900]

    // 中转数据数组，从查询数组的具体数据字符串中，每4个一组，组成16进制，然后转为10进制得到最终的数据
    let conversionList = [
      parseInt('0x' + processingData.slice(0, 5)).toString(),

      parseInt('0x' + processingData.slice(5, 10)).toString(),

      parseInt('0x' + processingData.slice(10, 15)).toString(),

      parseInt('0x' + processingData.slice(15, 20)).toString(),

      parseInt('0x' + processingData.slice(20, 25)).toString(),

      parseInt('0x' + processingData.slice(25, 30)).toString(),
    ]

    // 按照每组10进制，1-2-1-2的格式进行查询得到每个二十四节气的具体时间
    let resultList = [
      conversionList[0].slice(0, 1),

      conversionList[0].slice(1, 3),

      conversionList[0].slice(3, 4),

      conversionList[0].slice(4, 6),

      conversionList[1].slice(0, 1),

      conversionList[1].slice(1, 3),

      conversionList[1].slice(3, 4),

      conversionList[1].slice(4, 6),

      conversionList[2].slice(0, 1),

      conversionList[2].slice(1, 3),

      conversionList[2].slice(3, 4),

      conversionList[2].slice(4, 6),

      conversionList[3].slice(0, 1),

      conversionList[3].slice(1, 3),

      conversionList[3].slice(3, 4),

      conversionList[3].slice(4, 6),

      conversionList[4].slice(0, 1),

      conversionList[4].slice(1, 3),

      conversionList[4].slice(3, 4),

      conversionList[4].slice(4, 6),

      conversionList[5].slice(0, 1),

      conversionList[5].slice(1, 3),

      conversionList[5].slice(3, 4),

      conversionList[5].slice(4, 6),
    ]

    return {
      name: this.twentyFourSolarTerms[index - 1],
      month: Math.ceil(index / 2),
      day: Number(resultList[index - 1]),
    }
  }

  /**
   * 公历时间转换为干支纪年
   * @year 查询的公历年份
   * @month 查询的月份
   * @day 查询的日期
   * @返回当前年份的干支名称
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected trunkBranchChronology = (year: number, month: number, day = 1) => {
    // 获取到立春的年份
    const spring = this.twentyFourSolarTermsQuery(year, 3)

    // 声明承接的需要年份的变量
    let needYear: number

    // 判断如果输入的月份低于该年立春的月份，或者是月份相同时，日期晚于立春的日期
    if (month < spring.month || (month === spring.month && day < spring.day)) {
      // 则在干支纪年中还属于去年，故需要-1
      needYear = year - 1
    } else {
      // 如果都是大于的，则在干支纪年中属于今年，则赋予今年的时间
      needYear = year
    }

    // 按照公式进行计算天干地支
    let heavenlyStems = (needYear - 3) % 10

    let terrestrialBranch = (needYear - 3) % 12

    heavenlyStems === 0 && (heavenlyStems = 10) // 如果余数为0则为最后一个天干

    terrestrialBranch === 0 && (terrestrialBranch = 12) // 如果余数为0则为最后一个地支

    return (
      this.heavenlyStemsList[heavenlyStems - 1] +
      this.terrestrialBranchList[terrestrialBranch - 1]
    )
  }

  /**
   * 公历时间转换为干支纪月
   * @year 查询的公历年份
   * @month 查询的月份
   * @day 查询的日期
   * @返回一个对象
   * name:当前干支的名称
   * isDaySolarTerm:查询的天是否是节气，是的话返回对应的节气名称，否则为空
   * 干支月有个最大的区别为，立春为干支纪年的起始，立春的月份从地支寅开始，天干则按照谚语进行推论根据
   * 其次，后续月份的循环，二十四节气中奇数位数上的节气值为新月的开始，故只需确认到每月第一个二十四节气就可以推出当月的干支
   * 天干判断依据为
   * 甲己丙寅首，乙庚戊寅头，丙辛从庚起，丁壬壬寅居，戊癸甲寅求，周而复始行
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected trunkBranchMonth = (year: number, month: number, day: number) => {
    // 获取到立春的年份
    const spring = this.twentyFourSolarTermsQuery(year, 3)
    // 获取当前年份的干支首位(都统一为2月15日，方便后计算)
    const needYear = this.trunkBranchChronology(year, 2, 15).slice(0, 1)

    // 天干位数
    let heavenlyStemsIndex
    // 地支位数
    let terrestrialIndex = 2

    switch (needYear) {
      case '甲':
        heavenlyStemsIndex = 2
        break

      case '乙':
        heavenlyStemsIndex = 4
        break

      case '丙':
        heavenlyStemsIndex = 6
        break

      case '丁':
        heavenlyStemsIndex = 8
        break

      case '戊':
        heavenlyStemsIndex = 0
        break

      case '己':
        heavenlyStemsIndex = 2
        break
      case '庚':
        heavenlyStemsIndex = 4
        break
      case '辛':
        heavenlyStemsIndex = 6
        break
      case '壬':
        heavenlyStemsIndex = 8
        break
      case '癸':
        heavenlyStemsIndex = 0
        break

      default:
        break
    }

    // 获取当前月份中首个的节气日期
    let firstSolarTerm = this.twentyFourSolarTermsQuery(year, month * 2 - 1)
    let endSolarTerm = this.twentyFourSolarTermsQuery(year, month * 2)

    // 计算到底最后参与计算的月份为多少，如果早于每月第一个节气的时间，则计算的月份应当-1
    let needMonth =
      day < firstSolarTerm.day ? firstSolarTerm.month - 1 : firstSolarTerm.month
    // 计算首个节气日期与立春月份的差距，并进行相加到天干地支的位数上
    let disparityDay = needMonth - spring.month

    // 天干地支位置信息更新
    heavenlyStemsIndex += disparityDay
    terrestrialIndex += disparityDay

    // 判断是否超过了天干地支的月份数组的最大位置数，是的话则减去对应的长度,若是为负数，则是直接取最大位数
    heavenlyStemsIndex > 9
      ? (heavenlyStemsIndex -= 10)
      : heavenlyStemsIndex < 0
      ? (heavenlyStemsIndex = 9)
      : heavenlyStemsIndex
    terrestrialIndex > 11 ? (terrestrialIndex -= 12) : terrestrialIndex

    let isDaySolarTerm =
      firstSolarTerm.day === day
        ? firstSolarTerm.name
        : endSolarTerm.day === day
        ? endSolarTerm.name
        : false

    return {
      name:
        this.heavenlyStemsList[heavenlyStemsIndex] +
        this.terrestrialBranchList[terrestrialIndex],
      isDaySolarTerm,
    }
  }

  /**
   * 公历时间转换为干支纪日
   * @year 查询的公历年份
   * @month 查询的月份
   * @day 查询的日期
   * @返回当前日期的干支名称
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected trunkBranchDay = (year: number, month: number, day: number) => {
    // 调用距离农历原点的天数
    let needDay = this.timeDifference(year, month, day)

    // 农历原点+1天干支为 甲辰日
    // 我们需要将当前距离原点的总天数/10即整个天干（一共10天干）的个数 的余数则正好是当前天干的位置数
    // 地支因为是辰，在地支的位数为5，我们需要按照位数 -1 得到4，将其带入总天数中；取除以12的余数则是地支的位置信息
    return (
      this.heavenlyStemsList[needDay % 10] +
      this.terrestrialBranchList[(needDay + 4) % 12]
    )
  }

  /**
   * 公历转农历查询函数
   * @year 查询的公历年份
   * @month 查询的月份
   * @day 查询的日期
   * @返回一个对象
   * lunarCalendarYear:农历的年份
   * lunarCalendarMonth:农历的月份
   * lunarCalendarDay:农历的日期
   * chineseLunarCalendarYear:中文版农历的日期
   * chineseLunarCalendarMonth:中文版农历的日期
   * chineseLunarCalendarDay:中文版农历的日期
   * isLeapYear:是否是农历闰年
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected gregorianToLunar = (year: number, month: number, day: number) => {
    // 调用距离农历原点的天数
    let originDay = this.timeDifference(year, month, day)
    // 需要的年份和月份和日期变量
    let needYear: number,
      needChineseYear: string,
      needMonth: string,
      needChineseMonth: string,
      needDay: number,
      needChineseDay: string

    // 按照1900到2100年200年的时间进行循环
    // -------------------------------------------------------------------------------------------------------
    for (let index = 0; index < 200; index++) {
      // 查询当年农历的一年天数
      let thatYearDay = this.leapYearDays(1900 + index)
      // 如果此时剩余的天数值小于当年的天数则进行弹出
      if (originDay < thatYearDay) {
        // 给当前的农历年份赋值（因为此时天数）
        needYear = 1900 + index
        break
      }

      //  如果原点的天数大于当年的天数则继续相减
      originDay -= thatYearDay
    }

    // 从查询月份详情接口中结构出需要的参数
    // -------------------------------------------------------------------------------------------------------
    let { isLeapYear, leapMonth, monthObj } = this.leapYearMonth(needYear)

    // 月份规则查询数组(深克隆月份数据数组)
    let monthResultList = [...this.monthList]
    // 如果是闰年，则在对应的位置上加上闰年的标志+
    isLeapYear && monthResultList.splice(leapMonth, 0, leapMonth + '+')

    // 循环 monthResultList 将剩余的天数带入计算，得到具体的月份值
    for (let index = 0; index < monthResultList.length; index++) {
      // 获取月份规则的名称
      let value = monthResultList[index]
      // 根据规则名称得到具体的天数
      let monthDays = monthObj[value]

      // 如果剩余的天数小于本月的天数了，则进行弹出处理
      if (originDay < monthDays) {
        // 月份汉字表达式获取
        let monthName = this.lunarMonthAppellation[Number(value) - 1]

        // 需要的天数+日期赋值
        needDay = originDay += 1
        needMonth = value

        // 根据闰月规则进行拼接对应的月份汉字表达
        needChineseMonth = value.includes('+')
          ? '\u95f0' +
            this.lunarMonthAppellation[Number(value.slice(0, -1)) - 1] +
            '\u6708'
          : monthName + '\u6708'

        // 根据天数时间进行中文化转义
        let numberIndex = Math.trunc(needDay / 10)
        needChineseDay =
          needDay === 10
            ? '初十'
            : this.lunarDateTitle[numberIndex] +
              this.chineseNumber[needDay % 10]

        break
      }

      // 如果还是大于月份值，则继续相减
      originDay -= monthDays
    }

    // 年份文字化转义
    // -------------------------------------------------------------------------------------------------------
    let yearText = String(needYear)
    let text1 = this.chineseNumber[Number(yearText[0])]
    let text2 = this.chineseNumber[Number(yearText[1])]
    let text3 = this.chineseNumber[Number(yearText[2])]
    let text4 = this.chineseNumber[Number(yearText[3])]

    needChineseYear = text1 + text2 + text3 + text4

    return {
      lunarCalendarYear: needYear,
      chineseLunarCalendarYear: needChineseYear,
      lunarCalendarMonth: needMonth,
      chineseLunarCalendarMonth: needChineseMonth,
      lunarCalendarDay: needDay,
      chineseLunarCalendarDay: needChineseDay,
      isLeapYear,
    }
  }

  /**
   * @十二生肖查询函数
   * @year 查询的公历年份
   * @month 查询的月份
   * @day 查询的日期
   * @返回当前年份的生肖名称
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  protected zodiacQuery = (year: number, month: number, day: number) => {
    // 得到当前的农历年
    const { lunarCalendarYear } = this.gregorianToLunar(year, month, day)

    // 根据农历年计算当前的生肖名称
    return this.chineseZodiac[(lunarCalendarYear - 4) % 12]
  }

  /**
   * @当前日期转农历查询函数
   * @year 查询的公历年份
   * @month 查询的月份
   * @day 查询的日期
   * @返回一个对象
   * year:公历的年份
   * month:公历月份
   * day:公历日期
   * week:周几
   * chineseLunarCalendarYear:中文版农历的日期
   * chineseLunarCalendarMonth:中文版农历的日期
   * chineseLunarCalendarDay:中文版农历的日期
   * trunkBranchYears:干支年
   * trunkBranchMonths:干支月
   * trunkBranchDays:干支日
   * zodiac: 生肖
   * isLeapYear:是否是农历闰年
   * isGregorianYear:是否是公历闰年
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  lunarCalendarQuery = (
    year = new Date().getFullYear(),
    month = new Date().getMonth() + 1,
    day = new Date().getDate()
  ) => {
    // 同步用户查询的对象数据
    this.userInputTime.year = year
    this.userInputTime.month = month
    this.userInputTime.day = day

    // 判断限制条件
    // -------------------------------------------------------------------------------------------------------
    if (
      !this.Errors({
        year: true,
        month: true,
        gregorianCalendarMonthDay: true,
        lunarCalendarOrigin: true,
      })
    ) {
      return
    }

    // 执行农历查询函数
    // -------------------------------------------------------------------------------------------------------
    const {
      chineseLunarCalendarYear,
      chineseLunarCalendarMonth,
      chineseLunarCalendarDay,
      isLeapYear,
    } = this.gregorianToLunar(year, month, day)

    // 执行生肖查询函数
    // -------------------------------------------------------------------------------------------------------
    const zodiac = this.zodiacQuery(year, month, day)

    // 年份干支查询函数
    // -------------------------------------------------------------------------------------------------------
    const trunkBranchYears = this.trunkBranchChronology(year, month, day)

    // 月份干支查询函数
    // -------------------------------------------------------------------------------------------------------
    const { name: trunkBranchMonths, isDaySolarTerm: twentyFourSolarTermName } =
      this.trunkBranchMonth(year, month, day)

    // 日期干支查询函数
    // -------------------------------------------------------------------------------------------------------
    const trunkBranchDays = this.trunkBranchDay(year, month, day)

    // 星期获取
    // -------------------------------------------------------------------------------------------------------
    let week =
      '周' + this.weekList[new Date(`${year}-${month}-${day}`).getDay()]

    // 是否是公历闰年
    // -------------------------------------------------------------------------------------------------------
    let isGregorianYear = this.gregorianCalendarDay(year) === 366

    return {
      year,
      month,
      day,
      week,
      chineseLunarCalendarYear,
      chineseLunarCalendarMonth,
      chineseLunarCalendarDay,
      zodiac,
      trunkBranchYears,
      trunkBranchMonths,
      trunkBranchDays,
      twentyFourSolarTermName,
      isLeapYear,
      isGregorianYear,
    }
  }

  /**
   * @农历查询转换公历函数
   * @year 查询的农历年份
   * @month 查询的农历月份
   * @day 查询的农历日期
   * @Intercalation 是否致闰，默认false
   * @返回一个对象
   * year:公历的年份
   * month:公历月份
   * day:公历日期
   * week:周几
   * chineseLunarCalendarYear:中文版农历的日期
   * chineseLunarCalendarMonth:中文版农历的日期
   * chineseLunarCalendarDay:中文版农历的日期
   * trunkBranchYears:干支年
   * trunkBranchMonths:干支月
   * trunkBranchDays:干支日
   * zodiac: 生肖
   */
  // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
  gregorianCalendarQuery = (
    year = new Date().getFullYear(),
    month = new Date().getMonth() + 1,
    day = 1,
    isLeap = false
  ) => {
    // 判断限制条件
    // -------------------------------------------------------------------------------------------------------
    // 同步用户查询的对象数据
    this.userInputTime.year = year
    this.userInputTime.month = month
    this.userInputTime.day = day
    this.userInputTime.isLeap = isLeap

    // 判断限制条件
    // -------------------------------------------------------------------------------------------------------
    if (
      !this.Errors({
        year: true,
        month: true,
        lunarCalendarMonthDay: true,
      })
    ) {
      return
    }

    // 公历的年份+月份+日期
    let gregorianYear: number, gregorianMonth: number, gregorianDay: number

    // 距离农历原点天数收集,基于当前天数进行初始化
    // -------------------------------------------------------------------------------------------------------
    let totalDays = day

    for (let index = 0; index < year - 1900; index++) {
      // 将每年的天数加入距离天数中
      totalDays += this.leapYearDays(1900 + index)
    }

    // 使用农历所有月份查询函数
    const { isLeapYear, monthObj, leapMonth, leapMonthDay } =
      this.leapYearMonth(year)

    // 依据月份值进行循环查询
    for (let index = 1; index < month; index++) {
      // 将满足条件天数加入 收集中
      totalDays += monthObj[String(index)]
    }

    // 只有查询的年份是闰年时，且查询的月份是超过了或者当前闰年的闰月则将其天数加入总数
    !isLeap && isLeapYear && leapMonth < month && (totalDays += leapMonthDay)
    // 如果查询的是闰月，那么对其之前非闰的同月的天数加入查询函数
    isLeap && (totalDays += monthObj[String(leapMonth)])

    // 计算公历日期
    // -------------------------------------------------------------------------------------------------------
    // 农历原点为1900年1月31日，故需要对公历补正
    totalDays += 30

    for (let index = 0; index < 2100; index++) {
      // 获得当年的总天数
      let needDay = this.gregorianCalendarDay(1900 + index)

      // 若是当年天数大于或者等于目前剩余天数时，则弹出循环
      if (needDay >= totalDays) {
        // 计算出年份
        gregorianYear = 1900 + index
        break
      }

      // 将多余天数进行相减
      totalDays -= needDay
    }

    // 循环月份
    for (let index = 1; index < 13; index++) {
      // 获得当月的总天数
      let needDay = this.yearMonthDay(gregorianYear, index)

      // 判断如果当月天数和剩余天数相等或大于了
      if (totalDays <= needDay) {
        // 则弹出并对日期和月份赋值
        gregorianMonth = index
        gregorianDay = totalDays

        break
      }

      totalDays -= needDay
    }

    // 将算出来的公历日期带入农历转农历函数中
    return this.lunarCalendarQuery(gregorianYear, gregorianMonth, gregorianDay)
  }
}
